#include "crossbit/ExecutionEngine.h"

#include "crossbit/ELFMemoryImage.h"
#include "crossbit/SimpleTCache.h"
#include "crossbit/ShadowPage.h"
#include "crossbit/NextUseRegAllocator.h"
#include "arch/mips/MIPSInterpreter.h"
#include "arch/mips/MIPSProcessorState.h"
#include "arch/mips/MIPSVBasicBlockBuilder.h"
#include "arch/mips/MIPSSyscallHandler.h"
#include "arch/x86/X86Translator.h"
#include "arch/x86/X86TraceManager.h"
#include "arch/x86/X86.h"

////Begin///////////Added by Gujh for RaceBit
#include "crossbit/RBThread.h"
////End/////////////Added by Gujh for RaceBit


#include <signal.h>

#define TCACHE_SIZE	1024*1024*10

extern char** environ;

using namespace crossbit;

ShadowPage sp;
MIPSProcessorState ps;

void ctrl_c(int para)
{
	XTMemAddr entry = GLOBAL::tblock_stub->getSPC();
	XTFile fd = open("mem.dat",O_CREAT|O_RDWR);
	write(fd, &entry, sizeof(XTMemAddr) );
	ps.dumpToFile( fd );
	sp.dumpMemData( fd );
	close( fd );
	exit(para);
}

int main(int argc, char *argv[])
{
		//signal(SIGINT, ctrl_c);

		MemoryManager*	mm = MemoryManager::getInstance();
		SimpleTCache	tcache( TCACHE_SIZE, mm );

		ELFMemoryImage 	img( (XTPStr)argv[1], (XTUint32)(argc-1), (XTPStr*)&argv[1], (XTPStr*)environ );	
		MIPSInterpreter interp( &ps, &sp );
		MIPSVBasicBlockBuilder builder;
		NextUseRegAllocator alloc( 8, X86::movwMemToReg, X86::movwRegToMem, X86::movwRegToReg);
////Begin///////////Added|Modified by Gujh for RaceBit
		RBThreadManager rb(&img,&ps);
		X86Translator	tr( &ps, &alloc, &rb );
////End/////////////Added|Modified by Gujh for RaceBit
		X86TraceManager trace( mm );
		MIPSSyscallHandler sh(&ps, &img);


		ExecutionEngine ee( &img, mm, &trace, &interp, &builder, &tcache, &tr, &sh, &ps, &sp );

		XTMemAddr entry;
		XTFile fd = open("mem.dat",O_RDWR);
		read(fd, &entry, sizeof(XTMemAddr) );
		ps.loadFromFile( fd );
		sp.loadMemData( fd );
		close( fd );

		ee.run( entry );

		return 0;
}

